package ws;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import netty.util.StartAndStop;
import org.apache.commons.lang3.RandomUtils;
import test.PerformanceAnalyze;
import ws.client.WebSocketClient;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class OkHttpWsPublicBinary extends StartAndStop {

    static PerformanceAnalyze performanceAnalyze = new PerformanceAnalyze();

    private void performanceAnalyze(JSONObject jsonObject) {
        long creationTime = jsonObject.getLongValue("creationTime");
        if (creationTime != 0) {
            performanceAnalyze.delay(System.currentTimeMillis() - creationTime);
        }
    }

    public void start(String url, int size, String topic, String env) throws Exception {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);

        List<WebSocketClient> wsList = new LinkedList<>();

        for (int i = 0; i < size; i++) {
            WebSocketClient webSocketClient = WebSocketClient.create(url, msg -> {
                executor.execute(() -> {

                    JSONObject jsonObject = JSON.parseObject(msg);
                    if ("MergedMessage".equals(jsonObject.getString("type"))) {
                        JSONArray jsonArray = jsonObject.getJSONArray("messageList");
                        performanceAnalyze.getMeter().mark(jsonArray.size());
                        performanceAnalyze(jsonArray.getJSONObject(RandomUtils.nextInt(0, jsonArray.size())));
                    } else {
                        performanceAnalyze(jsonObject);
                    }
                });
            });
            wsList.add(webSocketClient);
        }

        for (WebSocketClient webSocket : wsList) {
            // {"op":"subscribe","id":"1645784808000","args":["1"]}
            Map<String, Object> subscribe = new HashMap<>();
            subscribe.put("id", String.valueOf(System.currentTimeMillis()));
            subscribe.put("op", "subscribe");
            List<String> args = new LinkedList<>();
            args.add(topic);
            subscribe.put("args", args);
            String command = JSON.toJSONString(subscribe);
            webSocket.send(command);

            System.out.println(command);
        }

        for (WebSocketClient webSocket : wsList) {
            Map<String, Object> ping = new HashMap<>();
            ping.put("id", String.valueOf(System.currentTimeMillis()));
            ping.put("op", "ping");

            executor.scheduleAtFixedRate(() -> webSocket.send(JSON.toJSONString(ping)), 1, 10, TimeUnit.SECONDS);
        }
    }

}
